package cn.ldf.keepaccounts.utils;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.ldf.keepaccounts.config.WxConfig;
import cn.ldf.keepaccounts.entity.vo.WxUserVO;
import cn.ldf.keepaccounts.exception.ServerException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author ldf
 * @code May there be no bugs in the world!
 */
@Slf4j
@Component
public class WxRequest {

    // 微信accessToken redis key
    private static final String WX_ACCESS_TOKEN = "wx:access_token";
    @Resource
    private WxConfig wxConfig;
    @Resource
    private RedisServer redisServer;


    /**
     * 获取微信accessToken
     *
     * @return accessToken 7200秒过期
     */
    public String getAccessToken() {
        // 先从redis中取未过期的token
        if (redisServer.hasKey(WX_ACCESS_TOKEN)){
            return redisServer.get(WX_ACCESS_TOKEN).toString();
        }
        String appId = wxConfig.getAppId();
        String secret = wxConfig.getSecret();
        String accessTokenUrl = wxConfig.getAccessTokenUrl();
        HttpResponse httpResponse = HttpRequest.get(accessTokenUrl)
                .form("grant_type", "client_credential")
                .form("appid", appId)
                .form("secret", secret)
                .timeout(3000).execute();
        String body = httpResponse.body();
        if (!httpResponse.isOk()) {
            log.error("获取微信accessToken请求异常,body:{}", body);
            throw new ServerException("获取微信用户信息请求异常");
        }
        JSONObject resp = JSONUtil.parseObj(body);
        String accessToken = resp.getStr("access_token");
        //存入redis
        redisServer.set(WX_ACCESS_TOKEN,accessToken,7100);
        return accessToken;
    }

    /**
     * 获取微信用户信息
     *
     * @param code 临时授权码
     * @return 结果集
     */
    public WxUserVO getOpenIdByCode(String code) {
        String getOpenIdUrl = wxConfig.getGetOpenIdUrl();
        HttpResponse httpResponse = HttpRequest.get(getOpenIdUrl)
                .form("appid", wxConfig.getAppId())
                .form("secret", wxConfig.getSecret())
                .form("js_code", code)
                .form("grant_type", "authorization_code")
                .execute();
        String body = httpResponse.body();
        if (!httpResponse.isOk()) {
            log.error("获取微信用户信息请求异常,body:{}", body);
            throw new ServerException("获取微信用户信息请求异常");
        }
        WxUserVO wxUserVO = JSONUtil.toBean(body, WxUserVO.class);
        if (ObjUtil.isNotEmpty(wxUserVO.getErrmsg())) {
            throw new ServerException(wxUserVO.getErrmsg());
        }
        return wxUserVO;
    }

    /**
     * 生成小程序二维码
     *
     * @param scene    场景值
     * @param pagePath 页面路径
     * @return 二维码流
     */
    public InputStream generateQrCode(String scene, String pagePath) {
        String generateQrCodeUrl = wxConfig.getGenerateQrCodeUrl() + "?access_token=" + getAccessToken();
        Map<String, Object> bodyMap = MapUtil.newHashMap();
        bodyMap.put("scene", scene);
        bodyMap.put("page", pagePath);
        bodyMap.put("check_path", false);
        bodyMap.put("env_version", "release");
        HttpResponse httpResponse = HttpRequest.post(generateQrCodeUrl)
                .body(JSONUtil.toJsonStr(bodyMap)).execute();
        if (!httpResponse.isOk()) {
            throw new ServerException("获取二维码失败");
        }
        return httpResponse.bodyStream();

    }

}
